//
//  DdxRatingView.m
//  TestingApp
//
//  Created by Amit Priyadarshi on 05/11/11.
//  Copyright 2011 Dbydx. All rights reserved.
//

#import "DdxRatingControl.h"
#import <QuartzCore/QuartzCore.h>
#import <CoreGraphics/CoreGraphics.h>
#define OffSet 0.9f
@interface DdxStarView : UIView {
	
	CGPoint points[10];
	UIColor* _clrFillColor;
	UIColor* _clrBorderColor;
	UIColor* selectedFillColor;
	UIColor* selectedBorderColor;
	UIColor* unselectedFillColor;
	UIColor* unselectedBorderColor;
	BOOL rated;
}
@property(nonatomic, retain) UIColor* fillColor;
@property(nonatomic, retain) UIColor* borderColor;
@property(nonatomic, retain) UIColor* selectedFillColor;
@property(nonatomic, retain) UIColor* selectedBorderColor;
@property(nonatomic, retain) UIColor* unselectedFillColor;
@property(nonatomic, retain) UIColor* unselectedBorderColor;
@property(nonatomic) BOOL rated;
- (void)animate;
- (void)setRated:(BOOL)rate animated:(BOOL)animated;
@end

@implementation DdxStarView
@synthesize fillColor=_clrFillColor;
@synthesize borderColor=_clrBorderColor;
@synthesize selectedFillColor;
@synthesize selectedBorderColor;
@synthesize unselectedFillColor;
@synthesize unselectedBorderColor;
@synthesize rated;

- (void)dealloc {
	[_clrFillColor release];
	_clrFillColor = nil;
	[_clrBorderColor release];
	_clrBorderColor = nil;
    [super dealloc];
}
- (id)initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    if (self) {
		points[0] = CGPointMake(0.5,0.025);
		points[1] = CGPointMake(0.654,0.338);
		points[2] = CGPointMake(1,0.388);
		points[3] = CGPointMake(0.75,0.631);
		points[4] = CGPointMake(0.809,0.975);
		points[5] = CGPointMake(0.5,0.813);
		points[6] = CGPointMake(0.191,0.975);
		points[7] = CGPointMake(0.25,0.631);
		points[8] = CGPointMake(0,0.388);
		points[9] = CGPointMake(0.346,0.338);
		for (int i=0; i<10; i++) {
			points[i].x = points[i].x * frame.size.width;
			points[i].y = points[i].y * frame.size.height;
		}
		self.selectedFillColor = [UIColor colorWithRed:0.983f green:0.857f blue:0.357f alpha:0.95];
		self.selectedBorderColor = [UIColor colorWithRed:0.886f green:0.657f blue:0.058f alpha:1.0f];
		self.unselectedFillColor = [UIColor colorWithRed:0.69f green:0.69f blue:0.69f alpha:0.95];
		self.unselectedBorderColor = [UIColor colorWithRed:0.457f green:0.457f blue:0.457f alpha:1.0f];
		_clrFillColor = self.selectedFillColor;
		_clrBorderColor = self.selectedBorderColor;
		
		self.backgroundColor = [UIColor clearColor];
		self.exclusiveTouch = NO;
		//		self.rated = NO;
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
	CGFloat lineWidth = rect.size.width * 0.030;
	CGContextRef context = UIGraphicsGetCurrentContext();
	CGContextSetShouldAntialias(context, true);
	
	CGContextSaveGState(context);
	CGContextBeginPath(context);
	CGContextAddLines(context, points, 10);
	CGContextClosePath(context);
	CGContextClip(context);  
	CGContextSetFillColorWithColor(context, [_clrFillColor CGColor]);
	CGContextFillRect(context, rect);
	CGContextRestoreGState(context);
	
	CGContextBeginPath(context);
	CGContextAddLines(context, points, 10);  
	CGContextClosePath(context);
	CGContextSetLineWidth(context, lineWidth);
	CGContextSetStrokeColorWithColor(context, [_clrBorderColor CGColor]);
	CGContextStrokePath(context);
}
- (void)layoutSubviews {
	CGFloat y = self.frame.size.width*0.05f;
	CGFloat x = self.frame.size.width*0.03f;
	self.layer.shadowColor = [[UIColor grayColor] CGColor];
	self.layer.shadowOpacity = 0.50f;
	self.layer.shadowRadius = x;
	self.layer.shadowOffset = CGSizeMake(x, y);
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
}
- (void)animate {
	CAKeyframeAnimation *scale = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
	scale.duration = 0.3;
	scale.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.9f],
					[NSNumber numberWithFloat:1.2f],
					[NSNumber numberWithFloat:1.0f],nil];
	
	[scale setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
	scale.removedOnCompletion = NO;
	scale.delegate = self;
	
	[self.layer addAnimation:scale forKey:@"popUp"];
}
#pragma mark - 
- (void)setRated:(BOOL)rate animated:(BOOL)animated{
	if (rate) {
		if (animated) [self animate];
		_clrFillColor = self.selectedFillColor;
		_clrBorderColor = self.selectedBorderColor;
	}
	else {
		_clrFillColor = self.unselectedFillColor;
		_clrBorderColor = self.unselectedBorderColor;
	}
	rated = rate;
	[self setNeedsDisplay];
}
- (void)setRated:(BOOL)rate{
	if (rate) {
		[self animate];
		_clrFillColor = self.selectedFillColor;
		_clrBorderColor = self.selectedBorderColor;
	}
	else {
		_clrFillColor = self.unselectedFillColor;
		_clrBorderColor = self.unselectedBorderColor;
	}
	rated = rate;
	[self setNeedsDisplay];
}

@end
/**************************************************************************************************************
 *                                                                                                            *
 *                                                                                                            *
 *************************************************************************************************************/
#pragma mark -
@interface DdxRatingControl()
- (void)willSelectStar:(id)sender;
- (void)didSelectStar:(id)sender;
- (void)animateStar:(DdxStarView*)sender;
@end


@implementation DdxRatingControl
@synthesize numberOfStars=_numberOfStars;
@synthesize rating;
@synthesize selectedFillColor;
@synthesize selectedBorderColor;
@synthesize unselectedFillColor;
@synthesize unselectedBorderColor;
- (void)dealloc {
	[_arrStars release];
	_arrStars = nil;
	
    [super dealloc];
}
- (void)setRating:(NSUInteger)rate {
	if (rate > _numberOfStars) return;
	if ([_arrStars count] < 1) return;
	for (DdxStarView* star in _arrStars)
	{
		[star setRated:NO];
	}
	CGFloat delay = 0.0f;
	DdxStarView* currentStar;
	for (int k = 0; k < rate; k++) {
		currentStar = (DdxStarView*)[_arrStars objectAtIndex:k];
		if (isTouchMoving) 
			[self animateStar:currentStar];
		else
			[self performSelector:@selector(animateStar:) withObject:currentStar afterDelay:delay];
		delay += 0.1;
	}
	
	rating = rate;
}
- (void)setNumberOfStars:(NSUInteger)stars {
	_numberOfStars = stars;
}
#pragma mark - Private methods
- (void)willSelectStar:(id)sender {
	
}
- (void)animateStar:(DdxStarView*)sender {
	[sender setRated:YES];
}
- (void)didSelectStar:(id)sender {
	DdxStarView* star = (DdxStarView*)sender;
	int index = star.tag;
	[self setRating:index+1];
	
	NSArray* selectors = [self actionsForTarget:_target forControlEvent:UIControlEventTouchUpInside];
	if (selectors && [selectors count] > 0) {
		for (NSString* methodName in selectors) {
			SEL method = NSSelectorFromString(methodName);
			if (_target && [_target respondsToSelector:method]) {
				[_target performSelector:method withObject:self];
			}
		}
	}	
}
#pragma mark -
- (id)initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    if (self) {
		self.selectedFillColor = [UIColor colorWithRed:0.983f green:0.857f blue:0.357f alpha:0.95];
		self.selectedBorderColor = [UIColor colorWithRed:0.886f green:0.657f blue:0.058f alpha:1.0f];
		self.unselectedFillColor = [UIColor colorWithRed:0.69f green:0.69f blue:0.69f alpha:0.95];
		self.unselectedBorderColor = [UIColor colorWithRed:0.457f green:0.457f blue:0.457f alpha:1.0f];
		self.numberOfStars = 5;
		_arrStars = [[NSMutableArray alloc] init];
		[self setBackgroundColor:[UIColor clearColor]];
		isTouchMoving = NO;
	}
    return self;
}
- (void)layoutSubviews {
	if (_numberOfStars < 1) _numberOfStars = 5;
	if ([_arrStars count] < _numberOfStars) {
		CGFloat side = self.frame.size.width/_numberOfStars;
		if (self.frame.size.height < side) 
			side = self.frame.size.height;
		CGFloat originalSide=side;
		side*=OffSet;
		CGFloat x = 0.0f;
		CGFloat y = (self.frame.size.height-side)/2.0f;
		CGRect rect;
		DdxStarView* _vwStar;
		_starSize = CGSizeMake(side, side);
		for (int starConut = 0; starConut < _numberOfStars; starConut++) {
			rect = CGRectMake(x, y, side, side);
			_vwStar = [[[DdxStarView alloc] initWithFrame:rect] autorelease];
			[self addSubview:_vwStar];
			[_arrStars addObject:_vwStar];
			[_vwStar setTag:starConut];
			[_vwStar setRated:NO animated:NO];
			[_vwStar setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin];
			x += originalSide;
			
			[_vwStar release];
		}
	}
	for (DdxStarView* star in _arrStars)
	{
		[star setSelectedFillColor:self.selectedFillColor];
		[star setSelectedBorderColor:self.selectedBorderColor];
		[star setUnselectedFillColor:self.unselectedFillColor];
		[star setUnselectedBorderColor:self.unselectedBorderColor];
	}	
	[self bringSubviewToFront:_imvUpperView];
}
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents {
	_target = [target retain];
	[super addTarget:target action:action forControlEvents:controlEvents];
}						 
#pragma mark -
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	isTouchMoving = NO;
	[super touchesBegan:touches withEvent:event];
	NSArray* arr = [touches allObjects];
	UITouch* touchPoint = [arr objectAtIndex:0];
	_ptStartTouch = [touchPoint locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	isTouchMoving = YES;
	[super touchesEnded:touches withEvent:event];
	NSArray* arr = [touches allObjects];
	UITouch* touchPoint = [arr objectAtIndex:0];
	_ptEndTouch = [touchPoint locationInView:self];
	CGPoint temp = [touchPoint locationInView:touchPoint.window];
	if (temp.x < self.frame.origin.x) {
		[self setRating:0];	
	} 
	else if (temp.x > (self.frame.origin.x+self.frame.size.width)){
		[self setRating:_numberOfStars];
	}
	else {
		for(int j = 0; j<_numberOfStars; j++) {
			UIView* currentStar = [_arrStars objectAtIndex:j];
			CGRect rect = currentStar.frame;
			rect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, self.frame.size.height);
			if(CGRectContainsPoint(rect, _ptEndTouch)) {
				if (_ptEndTouch.x < (rect.size.width/3+rect.origin.x)) [self setRating:j];
				else [self setRating:j+1];
			}
		}
	}	
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	[super touchesEnded:touches withEvent:event];
	if (!isTouchMoving) {
		NSArray* arr = [touches allObjects];
		UITouch* touchPoint = [arr objectAtIndex:0];
		_ptEndTouch = [touchPoint locationInView:self];
		CGPoint temp = [touchPoint locationInView:touchPoint.window];
		if (temp.x < self.frame.origin.x) {
			[self setRating:0];	
		} 
		else if (temp.x > (self.frame.origin.x+self.frame.size.width)){
			[self setRating:_numberOfStars];
		}
		else {
			for(int j = 0; j<_numberOfStars; j++) {
				UIView* currentStar = [_arrStars objectAtIndex:j];
				CGRect rect = currentStar.frame;
				rect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, self.frame.size.height);
				if(CGRectContainsPoint(rect, _ptEndTouch)) {
					if (_ptEndTouch.x < (rect.size.width/3+rect.origin.x)) [self setRating:j];
					else [self setRating:j+1];
				}
			}
		}
	}
	NSArray* selectors = [self actionsForTarget:_target forControlEvent:UIControlEventTouchUpInside];
	if (selectors && [selectors count] > 0) {
		for (NSString* methodName in selectors) {
			SEL method = NSSelectorFromString(methodName);
			if (_target && [_target respondsToSelector:method]) {
				[_target performSelector:method withObject:self];
			}
		}
	}			
}
@end
